using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
using Sprout.Cache.Redis;
using Sprout.Core;
using Sprout.Core.JsonConverters;
using Sprout.Repository;

namespace Sprout.Api.Test
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { private set; get; }

        readonly string policyName = "AllowOrigins";

        public void ConfigureServices(IServiceCollection services)
        {
            //获取程序的具体运行目录
            var basePath = AppContext.BaseDirectory;

            services
                 .AddControllers()
                 .AddNewtonsoftJson(options =>
                 {
                     //api返回时，long会转为 string
                     options.SerializerSettings.Converters = new List<Newtonsoft.Json.JsonConverter>() { new LongToStringConverter() };
                     // 不转小写
                     options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                     // 设置时间格式
                     options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                 })
                 ;

            //使用 IHttpClientFactory
            services.AddHttpClient();
            //用于获得 HttpContext
            services.AddHttpContextAccessor();


            #region swagger

            services
            .AddSwaggerGen(c =>
            {
                c.SwaggerDoc($"v1.0", new OpenApiInfo { Version = $"v1.0", Title = $"接口文档" });

                var xmlFiles = Configuration.GetSection("ServiceStartUp:NoteXmlFiles").Get<List<string>>();
                if (xmlFiles != null)
                {
                    foreach (var xmlFile in xmlFiles)
                    {
                        var xmlpath = Path.Combine(basePath, xmlFile);
                        c.IncludeXmlComments(xmlpath, true);
                    }
                }

                //如果类名相同（即使不同命名空间）必须如下配置：
                c.CustomSchemaIds(x => x.FullName);

                #region 设置全局
                //设定安全方案
                c.AddSecurityDefinition("Token", new OpenApiSecurityScheme
                {
                    Description = "设置全局的Token",
                    Name = "Token",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey
                });
                //该方案适用于哪些操作
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Token" }
                        },
                        new[] { "" }
                    }
                });
                #endregion
            });


            //使用 Newtonsoft 序列化JSON
            services.AddSwaggerGenNewtonsoftSupport();

            #endregion

            //基础库
            services.AddBasicsUtil();

            //数据库
            services.AddDataSource(Configuration);
            #region 跨域

            services.AddCors(options =>
                options.AddPolicy(policyName,
                builder =>
                {
                    builder.AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowAnyOrigin()  //允许所有
                        .SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
                })
            );
            #endregion
        }

        //autofac 新增
        public void ConfigureContainer(ContainerBuilder builder)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ServiceLocator.AutofacContainer = app.ApplicationServices.GetAutofacRoot();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            #region 使用swagger

            app.UseSwagger();
            //使用swagger-ui
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint($"/swagger/v1.0/swagger.json", $"V1.0 Docs");

                c.DefaultModelsExpandDepth(-1);//隐藏模型
                //折叠文档
                c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None);
            });
            #endregion

            //跨域
            app.UseCors(policyName);

            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });



            var redisConnections = Configuration.GetSection("RedisConnections").Get<List<RedisConnectionOption>>();
            var redisKeyOption = Configuration.GetSection("RedisKeys").Get<List<RedisKeyOption>>();
            RedisService.Initialize(redisConnections, redisKeyOption);

        }
    }
}
